﻿using System.Web.Mvc;
using LogikBug.ModularMvc.Factories;

namespace LogikBug.ModularMvc
{
	public class DynamicTypeModelBinder : DefaultModelBinder
	{
		#region Fields



		#endregion

		#region Constructors



		#endregion

		#region Properties



		#endregion

		#region Methods

		/// <summary>
		/// If the model type being bound is an interface, 
		/// this model binder will create a derived type from
		/// the interface, implement the interface and return
		/// the newly created dynamic type. If it is not an interface,
		/// the base <see cref="DefaultModelBinder"/> will be used.
		/// </summary>
		/// <param name="controllerContext">
		/// The context within which the controller operates.
		/// The context information includes the controller,
		/// HTTP content, request context, and route data.
		/// </param>
		/// <param name="bindingContext">
		/// The context within which the model is bound.
		/// The context includes information such as the
		/// model object, model name, model type, property
		/// filter, and value provider.
		/// </param>
		/// <exception cref="T:System.ArgumentNullException">
		/// The <paramref name="bindingContext "/>parameter is null.
		/// </exception>
		/// <returns>The bound object.</returns>
		public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
		{
			if (bindingContext.ModelType.IsInterface)
			{
				var newModel = ModelFactory.Current.Create(bindingContext.ModelType);

				bindingContext = new ModelBindingContext
				{
					ModelState = bindingContext.ModelState,
					ValueProvider = bindingContext.ValueProvider,
					ModelName = bindingContext.ModelName,
					FallbackToEmptyPrefix = bindingContext.FallbackToEmptyPrefix,
					ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(
						() => newModel,
						newModel.GetType()
					)
				};
			}

			return base.BindModel(controllerContext, bindingContext);
		}

		#endregion
	}
}
